/**
 * 
 */
package controller.xml;

import model.preprocessor.PreProcessorFactory;
import model.preprocessor.PreProcessorResult;
import model.session.ExecutionStatus;
import model.session.PreprocessorExecutionBlock;
import model.session.SessionBlock;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;

import controller.preprocessor.PreProcessor;

/**
 * Use to parse a {@link PreprocessorExecutionBlock} in the exported session in XML.
 * 
 * @author GRONOWSKI Stephane svan001@aol.com
 * 
 *         igsat 2010
 * 
 */
public class PreProcessorExecutionXMLHandler extends XMLHandler {

	private PreprocessorExecutionBlock		preprocBlock	= null;
	private PreProcessorExecutionXMLStatus	status			= PreProcessorExecutionXMLStatus.NONE;
	private ExecutionStatus					execStatus		= null;
	private Long							previousTime	= null;
	private PreProcessor					preproc			= null;
	private PreProcessorResult				result			= null;
	private PreProcessorFactory				factory;
	private SessionBlock					first			= null;

	public PreProcessorExecutionXMLHandler(SessionBlock first, PreProcessorFactory factory) {
		this.factory = factory;
		this.first = first;
	}

	@Override
	public boolean characters2(char[] ch, int start, int length) throws SAXException {
		throw new SAXException("unnexpecte behavior");
	}

	@Override
	public boolean endDocument2() throws SAXException {
		return false;
	}

	@Override
	public boolean endElement2(String uri, String localName, String qName) throws SAXException {
		switch (status) {
		case NONE:
			return false;

		case EXEC:
			if (qName.equals(XMLBaliseFormat.EXECUTION))
			{// ferme execution
				status = PreProcessorExecutionXMLStatus.NONE;
				execStatus = ((ExecutableXMLHandler) delegate).getExecstatus();
				previousTime = ((ExecutableXMLHandler) delegate).getPreviousTime();
				if (execStatus == null || previousTime == null)
					throw new SAXException("problem EXECUTION STATUS or PREVIOUS TIME");

				delegate = null;
				return true;
			}
			throw new SAXException("end of EXECUTION was expected");

		case PREPROC:
			if (qName.equals(XMLBaliseFormat.PREPROC))
			{// ferme preproc
				status = PreProcessorExecutionXMLStatus.NONE;
				preproc = ((PreProcessorXMLHandler) delegate).getPreproc();
				if (preproc == null)
					throw new SAXException("problem with PREPROC");

				delegate = null;
				return true;
			}
			throw new SAXException("end of PREPROC was expected");

		case PREPROC_RESULT:
			if (qName.equals(XMLBaliseFormat.PREPROC_RESULT))
			{// ferme preproc result
				status = PreProcessorExecutionXMLStatus.NONE;
				result = ((PreProcessorResultXMLHandler) delegate).getResult();
				if (result == null)
					throw new SAXException("problem with PREPROC RESULT");

				delegate = null;
				return true;
			}
			throw new SAXException("end of PREPROC RESULT was expected");
		}


		// attend une fin de balise qui existe pas...
		throw new SAXException("an other end of element was expected");
	}

	@Override
	public boolean startElement2(String arg0, String arg1, String arg2, Attributes arg3) throws SAXException {
		if (status != PreProcessorExecutionXMLStatus.NONE)
			throw new SAXException("already have a started element");

		if (arg2.equals(XMLBaliseFormat.PREPROC))
		{// balise preproc
			if (preproc != null)
				throw new SAXException("already have a PREPROC");

			// set les donnees pour recupere le preproc
			status = PreProcessorExecutionXMLStatus.PREPROC;
			delegate = new PreProcessorXMLHandler(factory);

			return true;
		}

		if (arg2.equals(XMLBaliseFormat.PREPROC_RESULT))
		{// balise result
			// set les donnees pour recupere le result
			status = PreProcessorExecutionXMLStatus.PREPROC_RESULT;
			delegate = new PreProcessorResultXMLHandler();
			return true;
		}

		if (arg2.equals(XMLBaliseFormat.EXECUTION))
		{// balise execution

			// set les donnees pour recupere le exec
			status = PreProcessorExecutionXMLStatus.EXEC;
			delegate = new ExecutableXMLHandler();
			return true;
		}
		// peut pas commencer balise qui existe pas
		throw new SAXException("unexpected balise: " + arg2);
	}

	/**
	 * Return the {@link PreprocessorExecutionBlock} if possible, null otherwise.
	 * 
	 * @return the {@link PreprocessorExecutionBlock}
	 */
	public PreprocessorExecutionBlock getPreprocBlock() {
		if (preprocBlock == null && result != null && preproc != null && execStatus != null)
		{// cree le block
			preprocBlock = new PreprocessorExecutionBlock(first, execStatus, preproc, result);
			preprocBlock.setPreviousExecutionTime(previousTime);
		}

		return preprocBlock;
	}

	/**
	 * Return the execStatus.
	 * 
	 * @return the execStatus
	 */
	public ExecutionStatus getExecStatus() {
		return execStatus;
	}

	/**
	 * Return the preproc.
	 * 
	 * @return the preproc
	 */
	public PreProcessor getPreproc() {
		return preproc;
	}

	/**
	 * Return the result.
	 * 
	 * @return the result
	 */
	public PreProcessorResult getResult() {
		return result;
	}


}
